package common.components.smileyenhanced
{
	import flash.events.Event;
	import flash.text.TextField;
	
	import mx.controls.TextArea;

	public class SmileyTextArea extends TextArea implements ISmileyTextEditable
	{	
		[Bindable]
		[Embed(source="smilies/smile.gif")]
		private var smileIconClass:Class;
		[Bindable]
		[Embed(source="smilies/sad.gif")]
		private var sadIconClass:Class;
		[Bindable]
		[Embed(source="smilies/veryhappy.gif")]
		private var happyIconClass:Class;
		[Bindable]
		[Embed(source="smilies/wink.gif")]
		private var winkIconClass:Class;
		[Bindable]
		[Embed(source="smilies/shocked.gif")]
		private var shockedIconClass:Class;
		[Bindable]
		[Embed(source="smilies/crying.gif")]
		private var cryingIconClass:Class;
		[Bindable]
		[Embed(source="smilies/confused.gif")]
		private var confusedIconClass:Class;
		[Bindable]
		[Embed(source="smilies/bored.gif")]
		private var boredIconClass:Class;
		[Bindable]
		[Embed(source="smilies/tongue.gif")]
		private var tongueIconClass:Class;
		
		public var smilies:Array = [
		    				  [[":)",":-)"],smileIconClass],
		    				  [[":(",":-("],sadIconClass],
		    				  [[":D",":-D"],happyIconClass],
		    				  [[";)",";-)"],winkIconClass],
		    				  [[":O",":o",":-o",":-O",":0",":-0"],shockedIconClass],
		    				  [[";(",";~(",";-("],cryingIconClass],
		    				  [[":s",":-s"],confusedIconClass],
		    				  [[":|",":-|"],boredIconClass],
		    				  [[":P",":p",":-p",":-P"],tongueIconClass]
		    				];
		
		private var smilyImages:Array = [];
		
		public function SmileyTextArea()
		{
			this.setStyle("leading",6);
		}
		
		override protected function createChildren():void
		{
			super.createChildren();
			this.addEventListener(Event.CHANGE, handleTextInput);

//			this.textField.antiAliasType = AntiAliasType.ADVANCED;
		}
		
		public function setMultiline(b:Boolean):void
		{
			this.textField.multiline = b;	
		}
		
		// for single line
		public function truncateToFit(token:String):void
		{
			if ( this.textField.truncateToFit(token) )
			{			
				for(var i:int=0; i<this.smilyImages.length; i++)
				{
					var s:Smiley = Smiley(this.smilyImages[i]);
	
					if ( s.x + s.width > this.textField.getCharBoundaries(this.textField.text.length-3).x )
					{					
						s.killSelf();
						i--;
					}
				}
			}
		}
		
		public function getCharOfTextX(num:Number):Number
		{
			return this.textField.getCharBoundaries(num).x;
		}
		
		public function getCharOfTextY(num:Number):Number
		{
			return this.textField.getCharBoundaries(num).y;
		}
//		
		
//	    override public function set width(value:Number):void
//	    {
//	    	super.width = value;
//				    	
//			this.dispatchEvent(new Event("change", false, false));
//	    }
		
		public function get realText ():String 
		{
			var ind:int = 0;
			var res:String = "";
			
			this.smilyImages.sortOn("position",Array.NUMERIC);
			
			for(var i:int=0; i<this.smilyImages.length; i++){
				res += this.textField.text.substring(ind, Smiley(this.smilyImages[i]).position);
				res += Smiley(this.smilyImages[i]).text;
				ind = Smiley(this.smilyImages[i]).position+5;
			}
			res += this.textField.text.substring(ind);
			
			return res;
		}
		
		public function removeSmily (sm:Smiley):void 
		{
			if(sm.parent==this){
				this.removeChild(sm);
			}

			for(var i:int = 0; i<this.smilyImages.length; i++){
				if(this.smilyImages[i] == sm){
					this.smilyImages.splice(i, 1);
					break;
				}
			}
		}
		
		[Bindable]
		public function set realText (str:String):void 
		{
			while(this.smilyImages.length)
			{
				var sm:Smiley = this.smilyImages.pop();
								
				sm.killSelf();
			}
			
//			this.text = str;
			this.textField.text = str;
			
			this.textField.dispatchEvent(new Event(Event.CHANGE));
//			this.dispatchEvent(new Event("change", false, false));
		}
		
		override public function set htmlText (str:String):void 
		{
			super.htmlText = str;
			this.validateNow();
			this.textField.dispatchEvent(new Event(Event.CHANGE));
//			this.dispatchEvent(new Event("change", false, false));
		}
		
		public function addSmileyText(sm:String):void
		{
			if ( this.textField.text.length > this.maxChars )
				return;
			var pos:int = this.textField.caretIndex;
			this.textField.text = this.textField.text.substring(0,pos)+sm+this.textField.text.substring(pos);
			this.textField.dispatchEvent(new Event(Event.CHANGE));
//			this.dispatchEvent(new Event("change", false, false));
		}		

		public function getTextWidth():int
		{
			return this.textField.textWidth+10;	
		}
		
		private function handleTextInput (evt:Event):void
		{
//			evt.preventDefault();
//			var buf:String = "";
//			var t:TextField = this.textField;
//			var pos:int = t.caretIndex;
//			var newText:String = t.text.substring(0,pos)+evt.text+t.text.substring(pos);
//			t.text = newText;
//			t.setSelection(pos+evt.text.length,pos+evt.text.length);
			
			var buf:String = "";
			var t:TextField = TextField(this.textField);
			
			for(var i:int=0; i<t.text.length; i++) 
			{
				buf += t.text.charAt(i);
				var foundStart:Boolean = false;
				var found:Boolean = false;
				
				for(var j:int=0; j<this.smilies.length; j++)
				{
					
					var cur:Array = this.smilies[j][0];
					for(var k:int=0; k<cur.length; k++)
					{
						if(cur[k].substr(0,buf.length)==buf)
						{
							foundStart = true;
							
							if(cur[k].length == buf.length)
							{
								found = true;
								break;
							}
						}
					}
					if(found) break;
				}
				
				if(found)
				{
					var newSmily:Smiley = new Smiley(smilies[j][1], t, this, i-buf.length+1, buf);
					i += newSmily.replaceLength - buf.length;
					buf = "";
					this.smilyImages.push(newSmily);
				}
				
				if(!foundStart) buf = "";
				if(buf.length==3) buf = buf.substr(1,2);
			}
			
			this.smilyImages.sortOn("position",Array.NUMERIC);
			
			for (var s:int = 0; s<this.smilyImages.length; ++s)
			{
				var sm:Smiley = Smiley(this.smilyImages[s]);
				sm.handleChange();
				if (sm.killed)
					--s;
			}
			
			this.invalidateProperties();
			this.invalidateDisplayList();
		}
		
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth,unscaledHeight);
			
			for (var s:int = 0; s<this.smilyImages.length; ++s)
			{
				var sm:Smiley = Smiley(this.smilyImages[s]);
				sm.setPosition();
			}
		}
		
		public function getVerticalScrollPosition ():int {
			return this.verticalScrollPosition;
		}
	}
}